package com.selebash.runtime;

import com.selebash.config.Config;
import com.selebash.runtime.resource.ResourceManager;
import com.selebash.scripts.Script;
import com.selebash.utils.AnyToAnyConverter;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * @author sad
 */
public class ExecutionContext {

    private Config config;
    private final Stack<Script> mainScriptStack = new Stack<Script>();
    private NestedExecutionProcessor nestedExecutionSettings;
    private final Map<String, Script> scriptMap = new HashMap<String, Script>();
    private ResourceManager resourceManager;
    public Map<String, Object> variables = new HashMap<String, Object>();
    private Object lastResult;

    public Object getLastResult() {
        return lastResult;
    }

    public void setLastResult(Object lastResult) {
        this.lastResult = lastResult;
    }

    public void setVariable(String name, Object value) {
        variables.put(name.toLowerCase(), value);
    }

    public boolean hasVariable(String name){
        return variables.containsKey(name.toLowerCase());
    }
    
    public Object getVariableAsObject(String name) {
        return variables.get(name.toLowerCase());
    }

    public String getVariableAsString(String name) {
        Object value = variables.get(name.toLowerCase());
        return value == null ? "" : value.toString();
    }

    public int getVariableAsInteger(String name) {
        Object value = variables.get(name.toLowerCase());
        if (value == null) {
            return 0;
        }
        return (Integer) AnyToAnyConverter.convert(value.getClass(), int.class, value);
    }

    public float getVariableAsFloat(String name) {
        Object value = variables.get(name.toLowerCase());
        if (value == null) {
            return 0.0f;
        }
        return (Float) AnyToAnyConverter.convert(value.getClass(), float.class, value);
    }

    public double getVariableAsDouble(String name) {
        Object value = variables.get(name.toLowerCase());
        if (value == null) {
            return 0.0;
        }
        return (Double) AnyToAnyConverter.convert(value.getClass(), double.class, value);
    }

    public boolean getVariableAsBoolean(String name) {
        Object value = variables.get(name.toLowerCase());
        if (value == null) {
            return false;
        }
        return (Boolean) AnyToAnyConverter.convert(value.getClass(), boolean.class, value);
    }

    public ResourceManager getResourceManager() {
        return resourceManager;
    }

    public void setResourceManager(ResourceManager resourceManager) {
        this.resourceManager = resourceManager;
    }

    public Config getConfig() {
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    public Script getMainScript() {
        return mainScriptStack.peek();
    }

    public void setMainScript(Script mainScript) {
        this.mainScriptStack.push(mainScript);
    }

    public Map<String, Script> getScriptMap() {
        return scriptMap;
    }

    public boolean isRunNested() {
        return nestedExecutionSettings != null;
    }

    public NestedExecutionProcessor getNestedExecutionSettings() {
        return nestedExecutionSettings;
    }

    public void setRunNested(NestedExecutionProcessor nestedExecutionSettings) {
        this.nestedExecutionSettings = nestedExecutionSettings;
    }

}
